import * as THREE from 'three';
import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
const loader = new OBJLoader();

export default class {
  config = {
    color: '#fff',
    model: 'images/satellite.obj',
    speed: 0.3,
    scale: 10,
    opacity: 0.3,
    radius: 2000,
    rotate: [-70, 20, 100]
  };
  mesh = new THREE.Group();
  material: THREE.MeshBasicMaterial;
  lineMaterial: THREE.LineBasicMaterial;
  constructor(color) {
    this.config.color = color;
    this.createMaterial();
    this.createSatelliteModel();
    this.createSatelliteTrack();
    this.setRotate(this.config.rotate);
  }
  createSatelliteModel() {
    loader.load(this.config.model, model => {
      model.traverse(mesh => {
        if (mesh instanceof THREE.Mesh) {
          mesh.material = this.material;
        }
      });
      model.scale.x = model.scale.y = model.scale.z = this.config.scale;
      model.position.x = this.config.radius;
      this.mesh.add(model);
    });
  }
  createSatelliteTrack() {
    const list: number[] = [];
    for (let i = 0; i <= 128; i++) {
      const x: number = Math.cos((i / 64) * Math.PI) * this.config.radius;
      const y: number = Math.sin((i / 64) * Math.PI) * this.config.radius;
      list.push(x, y, 0);
    }
    const position = new THREE.Float32BufferAttribute(list, 3);
    const geometry = new THREE.BufferGeometry();
    geometry.setAttribute('position', position);
    this.mesh.add(new THREE.LineLoop(geometry, this.lineMaterial));
  }
  createMaterial() {
    const transparent = true;
    const color = new THREE.Color(this.config.color);
    this.material = new THREE.MeshBasicMaterial({ transparent, color });
    this.lineMaterial = new THREE.LineBasicMaterial({ transparent, color });
  }
  setRotate(data) {
    const x = (data[0] / 180) * Math.PI;
    const y = (data[1] / 180) * Math.PI;
    const z = (data[2] / 180) * Math.PI;
    this.mesh.setRotationFromEuler(new THREE.Euler(x, y, z, 'XYZ'));
  }
  setConfig(config) {
    this.config = config;
    this.setRotate(config.rotate);
  }
  update() {
    this.mesh.rotation.z -= 0.05 * this.config.speed;
  }
  setColor(color) {
    this.config.color = color;
    this.material.color = new THREE.Color(color);
    this.lineMaterial.color = new THREE.Color(color);
  }
}
